use std::cmp::min;
use std::fmt::format;

/// 双指针

/// 数组拆分 I
/// https://leetcode.cn/leetbook/read/array-and-string/c24he/
pub fn array_pair_sum(mut nums: Vec<i32>) -> i32 {
    if nums.is_empty() { return 0; }
    nums.sort();
    nums.into_iter().enumerate().filter(|e| e.0 % 2 == 0).map(|e| e.1).sum()
}

/// 两数之和 II - 输入有序数组
/// https://leetcode.cn/leetbook/read/array-and-string/cnkjg/
pub fn two_sum(numbers: Vec<i32>, target: i32) -> Vec<i32> {
    if numbers.len() < 2 {
        return vec![];
    }
    let mut l = 0usize;
    let mut r = numbers.len() - 1;
    loop {
        if numbers[l] + numbers[r] > target {
            r = r - 1;
        } else if numbers[l] + numbers[r] < target {
            l = l + 1;
        } else {
            return
                vec![(l + 1) as i32, (r + 1) as i32];
        }
        if r <= l {
            return vec![];
        }
    }
}

/// 移除元素
/// https://leetcode.cn/leetbook/read/array-and-string/cwuyj/
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
    if nums.is_empty() { return 0; }
    let mut p = 0;

    for i in 0..nums.len() {
        if nums[i] != val {
            nums.swap(p, i);
            p = p + 1;
        }
    }
    p as i32
}

/// 最大连续1的个数
/// https://leetcode.cn/leetbook/read/array-and-string/cd71t/
pub fn find_max_consecutive_ones(nums: Vec<i32>) -> i32 {
    let mut max = 0;
    let mut p = 0;
    let mut op = if nums[0] == 1 {
        max = 1;
        true
    } else { false };
    for i in 1..nums.len() {
        if nums[i] == 1 {
            if !op {
                p = i;
                op = true;
            }
            if i == nums.len() - 1 {
                max = std::cmp::max(max, i - p + 1);
            }
        } else {
            if op {
                max = std::cmp::max(i - p, max);
                op = false;
            }
        }
    }

    max as i32
}

/// 长度最小的子数组
/// https://leetcode.cn/leetbook/read/array-and-string/c0w4r/
pub fn min_sub_array_len(target: i32, mut nums: Vec<i32>) -> i32 {
    let mut ret = i32::MAX;

    let mut left = 0;
    let mut sum = 0;
    for (right, num) in nums.iter().enumerate() {
        sum += num;
        while sum - nums[left] >= target {
            sum -= nums[left];
            left += 1;
        }
        if sum >= target {
            ret = ret.min((right - left) as i32 + 1);
        }
    }

    ret = if ret == i32::MAX {
        0
    } else {
        ret
    };
    ret
}

#[test]
fn test_array_pair_sum() {
    let vec1 = vec![1, 2, 3, 4];
    let i = array_pair_sum(vec1);
    println!("{i}");

    let x = [1, 2, 3];
    let string = x.iter().map(|e| format!("{e}")).collect::<Vec<_>>();
    let x1: Vec<_> = string.iter().map(|e| atoi::atoi::<i32>(e.as_bytes()).unwrap_or_default()).collect();
    println!("{string:?}");
    println!("{x:?}");
}

#[test]
fn test_two_sum() {
    let vec1 = vec![2, 3, 4];
    let target = 6;

    let sum = two_sum(vec1, target);
    println!("{:?}", sum);
}

#[test]
fn test_remove_element() {
    let mut vec1 = vec![3, 2, 2, 3];

    let sum = remove_element(&mut vec1, 3);

    println!("{:?}", sum);
    println!("{:?}", &vec1[0..sum as usize]);
}

#[test]
fn test_find_max_consecutive_ones() {
    let mut vec1 = vec![1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1];

    let sum = find_max_consecutive_ones(vec1);
    println!("{:?}", sum);
}

#[test]
fn test_min_sub_array_len() {
    let vec1 = vec![1,2,3,4,5];
    let target = 11;
    let i = min_sub_array_len(target, vec1);
    println!("{}", i);
}
